package com.zmn.oms.services.impl.report;

import com.google.common.collect.Lists;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.office.ExcelUtil;
import com.zmn.oms.model.entity.report.ReportCoupAnalyse;
import com.zmn.oms.model.entity.report.ReportCoupAnalyseQuery;
import com.zmn.oms.model.vo.report.ReportCoupAnalyseVO;
import com.zmn.oms.persistence.interfaces.report.ReportCoupAnalyseDao;
import com.zmn.oms.services.interfaces.report.ReportCoupAnalyseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 优惠卷分析报表service
 *
 * @author: HuangYongJie
 * @version: v1.0
 * @since: 2019/11/4 19:13
 **/
@Service
@Slf4j
public class ReportCoupAnalyseServiceImpl implements ReportCoupAnalyseService {

    /**
     * excel的表头
     */
    private static final List fistRow = Lists.newArrayList(
            "批次名称",
            "优惠券发放量",
            "优惠券领取量",
            "领取率",
            "优惠券使用量",
            "使用率",
            "用劵订单量",
            "用劵新单量",
            "用劵拉新率",
            "用劵复购单量",
            "用户复购率",
            "使用周期（天）",
            "使用平均周期（天）",
            "优惠总金额",
            "用劵订单原价总额",
            "ROI"
    );

    @Autowired(required = false)
    private ReportCoupAnalyseDao reportCoupAnalyseDao;


    @Override
    public List<ReportCoupAnalyseVO> listPageReportCoupAnalyse(ReportCoupAnalyseQuery query) {
        Integer count = reportCoupAnalyseDao.countByQuery(query);
        if (NumberUtil.isNullOrZero(count)) {
            return Collections.emptyList();
        }
        query.setTotalCount(count);
        List<ReportCoupAnalyseVO> reportCoupAnalyseVOList = reportCoupAnalyseDao.listPageByQuery(query);
        //数据不为空的时候，则添加汇总行
        if (reportCoupAnalyseVOList != null && !reportCoupAnalyseVOList.isEmpty()) {
            ReportCoupAnalyseVO totalReportCoupAnalyse = reportCoupAnalyseDao.getTotalRowReportCoupAnalyse(query);
            reportCoupAnalyseVOList.add(0, totalReportCoupAnalyse);
        }
        return reportCoupAnalyseVOList;
    }

    @Override
    public List<ReportCoupAnalyse> listCloseAndExpirData() {
        return reportCoupAnalyseDao.listCloseAndExpirData();
    }


    /**
     * 新增数据
     *
     * @param reportCoupAnalyse
     */
    @Override
    public void addReportCoupAnalyse(ReportCoupAnalyse reportCoupAnalyse) {
        if (Objects.isNull(reportCoupAnalyse)) {
            return;
        }
        int addNum = reportCoupAnalyseDao.insert(reportCoupAnalyse);
        log.info("addReportCoupAnalyse:add {} row data ", addNum);
    }

    /**
     * 清除未过期并且未关闭的数据
     *
     * @return
     */
    @Override
    public int clearCloseAndExpirData() {
        int deleteNum = reportCoupAnalyseDao.deleteCloseAndExpirData();
        return deleteNum;
    }

    @Override
    public int deleteByKey(Integer batchId) {
        if (Objects.isNull(batchId)) {
            return 0;
        }
        return reportCoupAnalyseDao.deleteByKey(batchId);
    }

    /**
     * 批量删除
     * @param list
     * @return
     */
    @Override
    public int deleteBatchByKeyList(List<Integer> list) {
        if(list == null|| list.isEmpty()){
            return 0;
        }
        return reportCoupAnalyseDao.deleteBatchByKeyList(list);
    }
    /**
     * 导出excel
     *
     * @param query
     * @return
     */
    @Override
    public Workbook exportExcel(ReportCoupAnalyseQuery query) {
        Integer count = reportCoupAnalyseDao.countByQuery(query);
        if (count > query.getPageSize()) {
            count = query.getPageSize();
        }
        int pageSize = 200;
        if (count <= pageSize) {
            pageSize = count;
        }
        int totalPage = count / pageSize;
        if (count % pageSize != 0) {
            totalPage++;
        }

        query.setPageSize(pageSize);
        List<List> sheetData = Lists.newArrayList();
        sheetData.add(fistRow);
        for (int i = 1; i <= totalPage; i++) {
            query.setPagesNumber(i);
            List<ReportCoupAnalyseVO> dataList = reportCoupAnalyseDao.listPageByQuery(query);
            dataList.forEach(obj -> {
                List row = Lists.newArrayListWithCapacity(fistRow.size());
                row.add(obj.getBatchName());
                row.add(obj.getCoupGrantNum());
                row.add(obj.getCoupReceiveNum());
                row.add(rateDealWith(obj.getCoupReceiveNum(), obj.getCoupGrantNum()));
                row.add(obj.getCoupUseNum());
                row.add(rateDealWith(obj.getCoupUseNum(), obj.getCoupReceiveNum()));

                row.add(obj.getCoupOrderNum());
                row.add(obj.getCoupNewOrderNum());
                row.add(rateDealWith(obj.getCoupNewOrderNum(), obj.getCoupOrderNum()));
                row.add(obj.getCoutRepeatOrderNum());
                row.add(rateDealWith(obj.getCoutRepeatOrderNum(),obj.getCoupOrderNum()));

                row.add(obj.getUseCycle() + "/天");
                row.add(rateDealWith2(obj.getUseCycle(), obj.getCoupOrderNum()));

                row.add(obj.getCoupPriceAmount());
                row.add(obj.getOrderOriginalPriceAmount());
                row.add(rateDealWith((obj.getOrderOriginalPriceAmount() - obj.getCoupPriceAmount()), obj.getOrderOriginalPriceAmount()));

                sheetData.add(row);
            });
        }
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("sheet1");
        ExcelUtil.parseList(sheetData, sheet, false);
        return workbook;
    }

    /**
     * 百分比
     *
     * @return
     */
    public String rateDealWith(BigDecimal x, BigDecimal y) {
        try {
            x = x.multiply(new BigDecimal(100));
            BigDecimal rate = x.divide(y, 2, RoundingMode.HALF_UP);
            return rate.toString() + "%";
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    public String rateDealWith(Integer a, Integer b) {
        if (a == null || b == null || b.equals(0)) {
            return "--";
        }
        BigDecimal x = new BigDecimal(a);
        BigDecimal y = new BigDecimal(b);
        return rateDealWith(x, y);
    }

    public String rateDealWith(Long a, Long b) {
        if (a == null || b == null || b.equals(0L)) {
            return "--";
        }
        BigDecimal x = new BigDecimal(a);
        BigDecimal y = new BigDecimal(b);
        return rateDealWith(x, y);
    }

    /**
     * 除法运算
     *
     * @param a
     * @param b
     * @return
     */
    public String rateDealWith2(Integer a, Integer b) {
        if (a == null || b == null || b.equals(0)) {
            return "--";
        }
        BigDecimal x = new BigDecimal(a);
        BigDecimal y = new BigDecimal(b);
        BigDecimal rate = x.divide(y, 2, RoundingMode.HALF_UP);
        String result = String.valueOf(rate.doubleValue());
        if(StringUtils.isEmpty(result)){
            return "--";
        }
        return result + "/天";
    }


}
